/* This source file is part of the Delectable Engine.
 * For the latest info, please visit http://delectable.googlecode.com/
 *
 * Copyright (c) 2009-2010 Ryan Chew
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file GameWindow.h
 * @brief Application window.
 */

#ifndef __DBL_GAMEWINDOW_H_
#define __DBL_GAMEWINDOW_H_

// Chewable Headers //
#include <cbl/Chewable.h>
#include <cbl/Core/Event.h>
#include <cbl/Core/GameComponent.h>
#include <cbl/Core/GameService.h>
#include <cbl/Core/GameTime.h>
#include <cbl/Util/Property.h>

// Delectable Headers //
#include "dbl/Delectable.h"
#include "dbl/Core/GameWindowSettings.h"
#include "dbl/Core/GameWindowEvents.h"

namespace dbl
{
	// Forward Declarations //
	class IPlatformWindow;

	// Using directive.
	using cbl::Event;

	//! @brief Main application window object which wraps the OS-dependent implementation.
	//! The game window's update order is set to always be the first to
	//! be updated in a game application.
	class DBL_API GameWindow :
		public cbl::GameComponent
	{
	/***** Properties *****/
	public:
		//! Declare game window service.
		CBL_GAMESERVICE_TYPE( GameWindow );
		//! Game window settings.
		GETTER_AUTO_CREF( GameWindowSettings, Settings );
		//! Get game window handle.
		GameWindowHandle GetGameWindowHandle();

	/***** Events *****/
	public:
		Event< E::OnWindowResized >		OnWindowResized;	//!< Triggered when window is resized.
		Event< E::OnWindowCreated >		OnWindowCreated;	//!< Triggered when window is created.
		Event< E::OnWindowDestroyed >	OnWindowDestroyed;	//!< Triggered when window is destroyed.
		Event< E::OnWindowClosed >		OnWindowClosed;		//!< Triggered when window is closed.
		Event< E::OnWindowLostFocus >	OnWindowLostFocus;	//!< Triggered when window is loses focus.
		Event< E::OnWindowGainedFocus >	OnWindowGainedFocus;//!< Triggered when window is gains focus.
		Event< E::OnWindowFullscreen >	OnWindowFullscreen;	//!< Triggered when window toggles fullscreen mode.
		
		Event< E::OnWindowKeyDown >		OnWindowKeyDown;	//!< Triggered when a key is pressed down.
		Event< E::OnWindowKeyUp >		OnWindowKeyUp;		//!< Triggered when a key is released.
		Event< E::OnWindowKeyChar >		OnWindowKeyChar;	//!< Triggered when a key character is pressed.
		
		Event< E::OnWindowMouseMove >	OnWindowMouseMove;	//!< Triggered when mouse is moved.
		Event< E::OnWindowMouseDown >	OnWindowMouseDown;	//!< Triggered when mouse button is pressed down.
		Event< E::OnWindowMouseUp >		OnWindowMouseUp;	//!< Triggered when mouse button is released.
		Event< E::OnWindowMouseWheel >	OnWindowMouseWheel;	//!< Triggered when mouse wheel is moved.
		
		Event< E::OnWindowMouseEnter >	OnWindowMouseEnter;	//!< Triggered when mouse enters the window.
		Event< E::OnWindowMouseLeave >	OnWindowMouseLeave;	//!< Triggered when mouse leaves the window.

	/***** Public Methods *****/
	public:
		//! Constructor.
		//! @param	game		Pointer to game.
		explicit GameWindow( cbl::Game & game );
		//! Constructor.
		//! @param	game		Pointer to game.
		//! @param	settings	Game window settings.
		GameWindow( cbl::Game & game, const GameWindowSettings & settings );
		//! Destructor.
		//! Automatically destroys any existing window.
		~GameWindow();
		//! Initialise and create the game window.
		virtual void Initialise( void );
		//! Shutdown and destroy the game window.
		virtual void Shutdown( void );
		//! Update the game window.
		virtual void Update( const cbl::GameTime & time );
		//! Set the window settings.
		//! @param	settings	New window settings.
		void SetWindowSettings( const GameWindowSettings & settings );
		//! Set window position.
		//! @param	x			X position.
		//! @param	y			Y position.
		void SetPosition( cbl::Uint32 x, cbl::Uint32 y );
		//! Set window size.
		//! @param	size		Game window dimensions.
		void SetSize( const GameWindowSize & size );
		//! Set window title.
		//! @param	title		New window title.
		void SetTitle( const cbl::Char * const title );
		//! Set window style.
		//! @param	style		New window style.
		//! @see Delectable::GameWindowStyle::Options
		void SetStyle( cbl::Uint32 style );
		//! Set fullscreen window toggle.
		//! @param	state		Fullscreen state.
		void SetFullscreen( bool state );
		//! Show game window.
		//! @param	state		Visibility state.
		void Show( bool state );
		//! Show window cursor.
		//! @param	state		Cursor visibility state.
		void ShowCursor( bool state );

	/***** Private Members *****/
	private:
		IPlatformWindow			* mPlatformWindow;	//!< Platform-specific window implementation.
		GameWindowSettings		mSettings;			//!< Game window settings.
	};
}

#endif // __DBL_GAMEWINDOW_H_
